<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
  <title>智能排盘</title>
  <style>
  *{margin:0;padding:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;-o-box-sizing:border-box;box-sizing:border-box;outline:none}
  html{font-size:18px;font-family:"Microsoft Yahei","Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;}
  body{background-color:#f9ecb7;padding:5px;}
  h1{font-size:28px;font-weight:normal;color:#b98c51;border-bottom:1px solid #b9a874;padding:5px 0;}
  #input{margin-top:5px;font-size:18px;float:left;width:360px;height:120px;padding:5px;}
  .condition{float:left;padding:5px;}
  .error{border-color:red}
  table{margin:2px;clear:both;display:block;border-collapse:collapse;empty-cells:show;border:0;}
  td{padding:4px;text-align:center;white-space:nowrap;}
  td.left{text-align:left;}
  td.bazi{font-size:22px;font-weight:bold;}
  td.bold{font-weight:bold;}
  td.small{font-size:14px;}
  .tip{clear:both;margin-top:10px;font-size:13px;color:#773f0c;white-space:normal;}
  .red{color:#c40000;}
  @media (max-width: 900px) {
    html{font-size:calc(100vw/7.5);}
    body{padding:0.05rem;}
    h1{font-size:0.32rem;}
    #input{width:100%;height:1rem;padding:0.1rem;font-size:0.36rem;}
    .condition{padding:0.2rem;font-size:0.28rem;}
    td{padding:0.04rem;font-size:0.28rem;}
    td.bazi{font-size:0.34rem;}
    td.small{font-size:0.21rem;}
    td.hide{font-size:0;width:0;padding:0;}
    .tip{margin-top:0.1rem;font-size:0.24rem;}
  }
  </style>
</head>
<body>
  <h1>八字排盘 - 智能排盘</h1>
  <textarea id="input"></textarea>
  <div class="condition">
    <label><input id="gender_man" type="radio" name="gender" value="+" checked>男</label>
    <label><input id="gender_woman" type="radio" name="gender" value="-">女</label>
    <label><input type="checkbox" id="lunar">阴历</label>
    <label><input id="zi0" type="radio" name="zi" value="2" checked>晚子时日柱算当天</label>
    <label><input id="zi1" type="radio" name="zi" value="1">晚子时日柱算明天</label>
    <div class="tip">录入一段日期信息到框中，如199908121700+代表1999年8月12日17点生男。<br>1. +表示男，-表示女。<br>2. 三个连续空格表示阴历。<br>3. 月前有空格表示闰月，非闰月不生效。</div>
  </div>
  
  <div id="pan"></div>
<script src="libs/jquery.min.js"></script>
<script src="libs/highlight.min.js"></script>
<script src="libs/marked.min.js"></script>
<script src="common-source.js"></script>
<script src="lunar.js"></script>
<script>
(function(W,D){
  var setClass = function(el,v){
    try{
      el.className = v;
    }catch(e){
      el.setAttribute('class', v);
    }
  };
  var trim = function(s){
    return s.replace(/(^\s*)|(\s*$)/g, '');
　};
  var padding = function(n){
    return (n<10?'0':'') + n;
  };
  var selectSect = 2;
  var input = D.getElementById('input');
  var genderMan = D.getElementById('gender_man');
  var genderWoman = D.getElementById('gender_woman');
  var zi0 = D.getElementById('zi0');
  var zi1 = D.getElementById('zi1');
  var lunarCheck = D.getElementById('lunar');
  var result = D.getElementById('pan');
  
  var onChangeGender = function(){
    var v = input.value;
    var gender = genderMan.checked ? '+' : '-';
    if(/[+-]$/.test(v)){
      v = v.replace(/[+-]/g, gender);
    }else{
      v = v + gender;
    }
    input.value = v;
    onInput();
  };
  
  var onChangeZi = function(){
    selectSect = zi0.checked ? 2 : 1;
    onInput();
  };
  
  var onChangeLunar = function(){
    var v = input.value;
    if(/\s{3}/.test(v)){
      v = v.replace(/\s{3}/g, '');
    }else{
      v = '   '+v;
    }
    input.value = v;
    onInput();
  };
  
  var onInput = function(){
    var v = input.value;
    if(!/^\s*\d{4}\s*\d{2}\s*\d{2}\s*\d{2}\s*\d{2}\s*[+-]?$/.test(v)){
      setClass(input,'error');
      return;
    }
    lunarCheck.checked = /\s{3}/.test(v) ? 'checked' : '';
    setClass(input,'');
    compute();
  };
  
  var computeEightChar = function(lunar,solar,gender){
    var bazi = lunar.getEightChar();
    // 选择流派
    bazi.setSect(selectSect);
    var currentYear,startYunSolar,daYun,daYunSize,currentYun;
    if(-1!=gender){
      var date = new Date();
      currentYear = date.getFullYear();
      var yun = bazi.getYun(gender);
      startYunSolar = yun.getStartSolar();
      daYun = yun.getDaYun();
      daYunSize = daYun.length;
      var currentLunar = Lunar.fromDate(date);
      
      var yZhi = currentLunar.getYearZhiByLiChun();
      var yHideGan = LunarUtil.ZHI_HIDE_GAN[yZhi];
      var yShiShenZhi = [];
      for(var u=0,v=yHideGan.length;u<v;u++){
        yShiShenZhi.push(yHideGan[u]+'-'+LunarUtil.SHI_SHEN_ZHI[bazi.getDayGan()+yZhi+yHideGan[u]]);
      }
      
      var mZhi = currentLunar.getMonthZhi();
      var mHideGan = LunarUtil.ZHI_HIDE_GAN[mZhi];
      var mShiShenZhi = [];
      for(var u=0,v=mHideGan.length;u<v;u++){
        mShiShenZhi.push(mHideGan[u]+'-'+LunarUtil.SHI_SHEN_ZHI[bazi.getDayGan()+mZhi+mHideGan[u]]);
      }
      
      var rZhi = currentLunar.getDayZhi();
      var rHideGan = LunarUtil.ZHI_HIDE_GAN[rZhi];
      var rShiShenZhi = [];
      for(var u=0,v=rHideGan.length;u<v;u++){
        rShiShenZhi.push(rHideGan[u]+'-'+LunarUtil.SHI_SHEN_ZHI[bazi.getDayGan()+rZhi+rHideGan[u]]);
      }
      currentYun = {
        daYunShiShen:'',
        daYunShiShenZhi:[],
        liuNianGanZhi:currentLunar.getYearInGanZhiByLiChun(),
        liuNianShiShen:LunarUtil.SHI_SHEN_GAN[bazi.getDayGan() + currentLunar.getYearGanByLiChun()],
        liuNianShiShenZhi:yShiShenZhi,
        liuYueGanZhi:currentLunar.getMonthInGanZhi(),
        liuYueShiShen:LunarUtil.SHI_SHEN_GAN[bazi.getDayGan() + currentLunar.getMonthGan()],
        liuYueShiShenZhi:mShiShenZhi,
        liuRiGanZhi:currentLunar.getDayInGanZhi(),
        liuRiShiShen:LunarUtil.SHI_SHEN_GAN[bazi.getDayGan() + currentLunar.getDayGan()],
        liuRiShiShenZhi:rShiShenZhi
      };
      for(var i=0;i<daYunSize;i++){
        var d = daYun[i];
        if(d.getStartYear()<=currentYear&&currentYear<=d.getEndYear()){
          if(d.getGanZhi()){
            currentYun.daYunGanZhi = d.getGanZhi();
            currentYun.daYunShiShen = LunarUtil.SHI_SHEN_GAN[bazi.getDayGan() + d.getGanZhi().substr(0,1)];
            var dZhi = d.getGanZhi().substr(1);
            var dHideGan = LunarUtil.ZHI_HIDE_GAN[dZhi];
            var dShiShenZhi = [];
            for(var x=0,y=dHideGan.length;x<y;x++){
              dShiShenZhi.push(dHideGan[x]+'-'+LunarUtil.SHI_SHEN_ZHI[bazi.getDayGan()+dZhi+dHideGan[x]]);
            }
            currentYun.daYunShiShenZhi = dShiShenZhi;
          }
          break;
        }
      }
    }
    var s = '<table><tbody>';
    s += '<tr>';
    s += '<td>出生：</td>';
    s += '<td colspan="10" class="left">' + solar.getYear() + '年' + solar.getMonth() + '月' + solar.getDay() + '日(' + lunar.getMonthInChinese() + '月' + lunar.getDayInChinese() + ')' + padding(solar.getHour()) + ':' + padding(solar.getMinute()) +' 星期'+solar.getWeekInChinese()+ '</td>';
    s += '</tr>';
    
    s += '<tr>';
    s += '<td>节气：</td>';
    var prevJieQi = lunar.getPrevJie();
    var jieQiSolar = prevJieQi.getSolar();
    s += '<td colspan="10" class="left">' + prevJieQi.getName() + '：' + jieQiSolar.getMonth() + '月' + jieQiSolar.getDay() + '日' + padding(jieQiSolar.getHour()) + ':' + padding(jieQiSolar.getMinute()) + '；';
    var nextJieQi = lunar.getNextJie();
    jieQiSolar = nextJieQi.getSolar();
    s += nextJieQi.getName() + '：' + jieQiSolar.getMonth() + '月' + jieQiSolar.getDay() + '日' + padding(jieQiSolar.getHour()) + ':' + padding(jieQiSolar.getMinute());
    s += '</td>';
    s += '</tr>';
    
    var riGan = '日干';
    var baziTitle = '八字';
    var daYunTitle = '大运';
    var liuNianTitle = '流年';
    var liuYueTitle = '流月';
    if(1==gender){
      baziTitle = '乾造';
      riGan = '元男';
    }else if(0==gender){
      baziTitle = '坤造';
      riGan = '元女';
    }else{
      daYunTitle = '';
      liuNianTitle = '';
      liuYueTitle = '';
    }
    s += '<tr>';
    s += '<td rowspan="4" valign="top">' + baziTitle + '：</td>';
    s += '<td>年柱</td>';
    s += '<td>月柱</td>';
    s += '<td>日柱</td>';
    s += '<td>时柱</td>';
    s += '<td></td>';
    s += '<td>'+daYunTitle+'</td>';
    s += '<td>'+liuNianTitle+'</td>';
    s += '<td>'+liuYueTitle+'</td>';
    s += '<td colspan="2"></td>';
    s += '</tr>';
    s += '<tr>';
    s += '<td class="small">' + bazi.getYearShiShenGan() + '</td>';
    s += '<td class="small">' + bazi.getMonthShiShenGan() + '</td>';
    s += '<td class="small">' + riGan + '</td>';
    s += '<td class="small">' + bazi.getTimeShiShenGan() + '</td>';
    if(currentYun){
      s += '<td></td>';
      s += '<td class="small">'+currentYun.daYunShiShen+'</td>';
      s += '<td class="small">'+currentYun.liuNianShiShen+'</td>';
      s += '<td class="small">'+currentYun.liuYueShiShen+'</td>';
      s += '<td colspan="2"></td>';
    }else{
      s += '<td colspan="6"></td>';
    }
    s += '</tr>';
    s += '<tr>';
    s += '<td class="bazi">' + bazi.getYearGan()+'<br>'+bazi.getYearZhi() + '</td>';
    s += '<td class="bazi">' + bazi.getMonthGan()+'<br>'+bazi.getMonthZhi() + '</td>';
    s += '<td class="bazi">' + bazi.getDayGan()+'<br>'+bazi.getDayZhi() + '</td>';
    s += '<td class="bazi">' + bazi.getTimeGan()+'<br>'+bazi.getTimeZhi() + '</td>';
    if(currentYun){
      s += '<td></td>';
      s += '<td class="bazi">'+(currentYun.daYunGanZhi?(currentYun.daYunGanZhi.substr(0,1)+'<br>'+currentYun.daYunGanZhi.substr(1)):'')+'</td>';
      s += '<td class="bazi">'+currentYun.liuNianGanZhi.substr(0,1)+'<br>'+currentYun.liuNianGanZhi.substr(1)+'</td>';
      s += '<td class="bazi">'+currentYun.liuYueGanZhi.substr(0,1)+'<br>'+currentYun.liuYueGanZhi.substr(1)+'</td>';
      s += '<td colspan="2"></td>';
    }else{
      s += '<td colspan="6"></td>';
    }
    s += '</tr>';
    s += '<tr>';
    var hideGan = bazi.getYearHideGan();
    var shiShenZhi = bazi.getYearShiShenZhi();
    s += '<td valign="top" class="small">';
    for(var i=0,j=hideGan.length;i<j;i++){
      s += '<div' + (i==0?' class="red"':'') + '>'
      s += hideGan[i] + '-' + shiShenZhi[i];
      s += '</div>';
    }
    s += '</td>';
    hideGan = bazi.getMonthHideGan();
    shiShenZhi = bazi.getMonthShiShenZhi();
    s += '<td valign="top" class="small">';
    for(var i=0,j=hideGan.length;i<j;i++){
      s += '<div' + (i==0?' class="red"':'') + '>'
      s += hideGan[i] + '-' + shiShenZhi[i];
      s += '</div>';
    }
    s += '</td>';
    hideGan = bazi.getDayHideGan();
    shiShenZhi = bazi.getDayShiShenZhi();
    s += '<td valign="top" class="small">';
    for(var i=0,j=hideGan.length;i<j;i++){
      s += '<div' + (i==0?' class="red"':'') + '>'
      s += hideGan[i] + '-' + shiShenZhi[i];
      s += '</div>';
    }
    s += '</td>';
    hideGan = bazi.getTimeHideGan();
    shiShenZhi = bazi.getTimeShiShenZhi();
    s += '<td valign="top" class="small">';
    for(var i=0,j=hideGan.length;i<j;i++){
      s += '<div' + (i==0?' class="red"':'') + '>'
      s += hideGan[i] + '-' + shiShenZhi[i];
      s += '</div>';
    }
    s += '</td>';
    if(currentYun){
      s += '<td></td>';
      s += '<td class="small" valign="top">';
      for(var i=0,j=currentYun.daYunShiShenZhi.length;i<j;i++){
        s += '<div' + (i==0?' class="red"':'') + '>'
        s += currentYun.daYunShiShenZhi[i];
        s += '</div>';
      }
      s += '</td>';
      s += '<td class="small" valign="top">';
      for(var i=0,j=currentYun.liuNianShiShenZhi.length;i<j;i++){
        s += '<div' + (i==0?' class="red"':'') + '>'
        s += currentYun.liuNianShiShenZhi[i];
        s += '</div>';
      }
      s += '</td>';
      s += '<td class="small" valign="top">';
      for(var i=0,j=currentYun.liuYueShiShenZhi.length;i<j;i++){
        s += '<div' + (i==0?' class="red"':'') + '>'
        s += currentYun.liuYueShiShenZhi[i];
        s += '</div>';
      }
      s += '</td>';
      s += '<td colspan="2"></td>';
    }else{
      s += '<td colspan="6"></td>';
    }
    s += '</tr>';
    
    if(-1!=gender){
      s += '<tr>';
      s += '<td>起运：</td>';
      s += '<td colspan="10" class="left">'+startYunSolar.getYear()+'年'+startYunSolar.getMonth()+'月'+startYunSolar.getDay()+'日</td>';
      s += '</tr>';
      
      s += '<tr>';
      s += '<td>周岁：</td>';
      for(var i=0;i<daYunSize;i++){
        var d = daYun[i];
        s += '<td'+(i>=daYunSize-2?' class="hide"':'')+'>' + d.getStartAge() + '</td>';
      }
      s += '</tr>';
      s += '<tr>';
      s += '<td>换运：</td>';
      for(var i=0;i<daYunSize;i++){
        var d = daYun[i];
        s += '<td'+(i>=daYunSize-2?' class="hide"':'')+'>' + d.getStartYear() + '</td>';
      }
      s += '</tr>';
      s += '<tr>';
      s += '<td>十神：</td>';
      for(var i=0;i<daYunSize;i++){
        var d = daYun[i];
        var shiShen = LunarUtil.SHI_SHEN_GAN[bazi.getDayGan() + d.getGanZhi().substr(0,1)];
        s += '<td class="small'+(i>=daYunSize-2?' hide':'')+'">' + (shiShen ? shiShen:'') + '</td>';
      }
      s += '</tr>';
      s += '<tr>';
      s += '<td>运程：</td>';
      for(var i=0;i<daYunSize;i++){
        var d = daYun[i];
        var ganZhi = d.getGanZhi();
        if(!ganZhi){
          s += '<td class="red">童限</td>';
        }else{
          s += '<td class="bold'+(d.getStartYear()<=currentYear&&currentYear<=d.getEndYear()?' red':'')+(i>=daYunSize-2?' hide':'')+'">' + ganZhi + '</td>';
        }
      }
      s += '</tr>';
      s += '<tr>';
      s += '<td valign="top">流年：</td>';
      for(var i=0;i<daYunSize;i++){
        var d = daYun[i];
        var liuNian = d.getLiuNian();
        s += '<td valign="top"'+(i>=daYunSize-2?' class="hide"':'')+'>';
        for(var x=0,y=liuNian.length;x<y;x++){
          var n = liuNian[x];
          s += '<div'+(n.getYear()==currentYear?' class="red"':'')+'>'+n.getGanZhi() + '</div>';
        }
        s += '</td>';
      }
      s += '</tr>';
    }
    
    s += '</tbody></table>';
    result.innerHTML = s;
  };
  
  var computeLunar = function(year,month,day,hour,minute,gender){
    var lunar = Lunar.fromYmdHms(year,month,day,hour,minute,0);
    var solar = lunar.getSolar();
    computeEightChar(lunar,solar,gender);
  };
  
  var computeSolar = function(year,month,day,hour,minute,gender){
    var solar = Solar.fromYmdHms(year,month,day,hour,minute,0);
    var lunar = solar.getLunar();
    computeEightChar(lunar,solar,gender);
  };
  
  var compute = function(){
    result.innerHTML = '';
    var v = trim(input.value);
    if(lunarCheck.checked){
      var year = parseInt(v.substr(0,4));
      v = v.substr(4);
      var leapMonth = false;
      if(v.indexOf(' ') == 0){
        leapMonth = true;
      }
      v = trim(v);
      var month = parseInt(v.substr(0,2),10);
      if(leapMonth){
        if(LunarYear.fromYear(year).getLeapMonth()===month){
          month = -month;
        }
      }
      
      v = trim(v.substr(2));
      var day = parseInt(v.substr(0,2),10);
      v = trim(v.substr(2));
      var hour = parseInt(v.substr(0,2),10);
      v = trim(v.substr(2));
      var minute = parseInt(v.substr(0,2),10);
      v = trim(v.substr(2));
      var gender = -1;
      if('+'==v){
        gender = 1;
      }else if('-'==v){
        gender = 0;
      }
      if(year<1||year>9999){
        return;
      }
      if(month>=0&&(month<1||month>12)){
        return;
      }
      if(month<0&&(month<-12||month>-1)){
        return;
      }
      if(day<1||day>30){
        return;
      }
      if(hour<0||hour>23){
        return;
      }
      if(minute<0||minute>59){
        return;
      }
      computeLunar(year,month,day,hour,minute,gender);
    }else{
      var year = parseInt(v.substr(0,4));
      v = trim(v.substr(4));
      var month = parseInt(v.substr(0,2),10);
      v = trim(v.substr(2));
      var day = parseInt(v.substr(0,2),10);
      v = trim(v.substr(2));
      var hour = parseInt(v.substr(0,2),10);
      v = trim(v.substr(2));
      var minute = parseInt(v.substr(0,2),10);
      v = trim(v.substr(2));
      var gender = -1;
      if('+'==v){
        gender = 1;
      }else if('-'==v){
        gender = 0;
      }
      if(year<1||year>9999){
        return;
      }
      if(month<1||month>12){
        return;
      }
      if(day<1||day>31){
        return;
      }
      if(hour<0||hour>23){
        return;
      }
      if(minute<0||minute>59){
        return;
      }
      computeSolar(year,month,day,hour,minute,gender);
    }
  };
  
  input.oninput = onInput;
  input.onpropertychange = onInput;
  genderMan.onclick = onChangeGender;
  genderWoman.onclick = onChangeGender;
  zi0.onclick = onChangeZi;
  zi1.onclick = onChangeZi;
  lunarCheck.onclick = onChangeLunar;
})(window,document);
</script>
</body>
</html>